home *** CD-ROM | disk | FTP | other *** search
- .XALL
- PAGE ,132
- TITLE DASM80 - 14 SEP 1985
-
- ; ****************************************************************
- ; ** **
- ; ** MS-DOS 8080/8085 DISASSEMBLER **
- ; ** **
- ; **............................................................**
- ; ** **
- ; ** DASM80 DISASSEMBLES 8080/8085 INTEL HEX FILES. **
- ; ** **
- ; ****************************************************************
-
- ; ..... MODULE CONNECTION POINTS .....
-
- EXTRN MNEM:NEAR ; MNEMONIC TABLE
- EXTRN BYTES:NEAR ; BYTES TABLE
-
- ; ..... MACROS .....
-
- DISKRD MACRO NUMBYTE ; READ SPECIFIED NUMBER OF BYTES FROM DISK
- LOCAL OK ; OK IS A LOCAL SYMBOL
- MOV AH,READ ; LOAD READ COMMAND
- MOV BX,RDHAND ; LOAD READ FILE HANDLE
- MOV CX,NUMBYTE ; LOAD NUMBER OF CHARACTERS TO BE READ
- MOV DX,OFFSET DSKBUF; POINT TO DISK BUFFER
- INT DOSFUNC ; READ FROM INPUT FILE - ERROR?
- JNC OK ; NO - DONE
-
- JMP DSKERR ; YES - DISPLAY ERROR
-
- OK:
- ENDM ;
-
- DISKWR MACRO NUMBYTE ; WRITE SPECIFIED NUMBER OF BYTES TO DISK
- LOCAL OK ; OK IS A LOCAL SYMBOL
- MOV AH,WRITE ; LOAD WRITE COMMAND
- MOV BX,WRHAND ; LOAD WRITE FILE HANDLE
- MOV CX,NUMBYTE ; LOAD NUMBER OF CHARACTERS TO WRITE
- MOV DX,OFFSET DSKBUF; POINT TO DISK BUFFER
- INT DOSFUNC ; WRITE TO OUTPUT - ERROR?
- JNC OK ; NO - DONE
-
- JMP DSKERR ; YES - DISPLAY ERROR
-
- OK:
- ENDM ;
- PAGE
- ; ..... DOS COMMANDS .....
-
- DOSFUNC EQU 21H ; DOS FUNCTION INTERRUPT
- PR_STR EQU 09H ; DOS FUNCTION PRINT STRING COMMAND
- CREATE EQU 3CH ; CREATE FILE COMMAND
- OPEN EQU 3DH ; OPEN FILE COMMAND
- CLOSE EQU 3EH ; CLOSE FILE COMMAND
- READ EQU 3FH ; READ FILE COMMAND
- WRITE EQU 40H ; WRITE FILE COMMAND
- RDACC EQU 0 ; READ FILE ACCESS CODE
- WRACC EQU 1 ; WRITE FILE ACCESS CODE
- WRATT EQU 0 ; WRITE FILE ATTRIBUTE CODE
-
-
- ; ..... CONSTANTS .....
-
- MEMLEN EQU 2000H ; LENGTH OF MEMORY BUFFER
- MAXLEN EQU 80 ; MAXIMUM FILE NAME LENGTH
- CR EQU 0DH ; ASCII <CR>
- LF EQU 0AH ; ASCII LINE FEED
- RS EQU 1EH ; ASCII RECORD SEPARATOR
- TAB EQU 09H ; ASCII TAB
- DATIND EQU 00H ; HEX FILE DATA RECORD INDICATOR
- EOFIND EQU 01H ; HEX FILE END OF FILE INDICATOR
- PAGE
- STACK SEGMENT STACK ; STACK SEGMENT
- DW 1024 DUP (?) ; 1024 LEVELS OF STACK
- STACK ENDS
-
- DATA SEGMENT PUBLIC ; DATA SEGMENT
-
- ; ****************************************************************
- ; ** **
- ; ** MISCELLANEOUS STRINGS **
- ; ** **
- ; ****************************************************************
-
- MSGORG DB ';',CR,LF,TAB,'ORG',TAB,'0'
- LENORG EQU $-MSGORG
-
- MSGEND DB ';',CR,LF,TAB,'END',CR,LF
- LENEND EQU $-MSGEND
-
-
- ; ****************************************************************
- ; ** **
- ; ** ERROR STRINGS **
- ; ** **
- ; ****************************************************************
-
- MBCOM DB CR,LF,'COMMAND LINE ERROR',CR,LF,LF,'$'
-
- MBHEX DB CR,LF,'BAD HEX DATA',CR,LF,LF,'$'
-
- MDISK0 DB CR,LF,'ERROR 0 - DISK FULL',CR,LF,LF,'$'
-
- MDISK1 DB CR,LF,'ERROR 1 - INVALID FUNCTION',CR,LF,LF,'$'
-
- MDISK2 DB CR,LF,'ERROR 2 - FILE NOT FOUND',CR,LF,LF,'$'
-
- MDISK3 DB CR,LF,'ERROR 3 - PATH NOT FOUND',CR,LF,LF,'$'
-
- MDISK4 DB CR,LF,'ERROR 4 - TOO MANY OPEN FILES',CR,LF,LF,'$'
-
- MDISK5 DB CR,LF,'ERROR 5 - ACCESS DENIED',CR,LF,LF,'$'
-
- MDISK6 DB CR,LF,'ERROR 6 - INVALID FILE HANDLE',CR,LF,LF,'$'
-
- MUKNOW DB CR,LF,'UNKNOWN DISK ERROR',CR,LF,LF,'$'
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** PROGRESS MESSAGE STRINGS **
- ; ** **
- ; ****************************************************************
-
- MRCOM DB CR,LF,'READING COMMAND LINE',CR,LF,'$'
-
- MOPENR DB 'OPENING READ FILE',CR,LF,'$'
-
- MCHEX DB 'CONVERTING HEX FILE',CR,LF,'$'
-
- MOPENW DB 'CLOSING READ AND OPENING WRITE FILE',CR,LF,'$'
-
- MDISS DB 'DISASSEMBLING CONVERTED DATA',CR,LF,'$'
-
- MCLOSW DB 'CLOSING WRITE FILE',CR,LF,'$'
-
- MEXIT DB 'EXITING TO DOS',CR,LF,LF,'$'
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** MEMORY ASSIGNMENTS **
- ; ** **
- ; ****************************************************************
-
- DSKBUF DB 80 DUP (?) ; DISK I/O BUFFER
-
- DSKCNT DW (?) ; DISK BUFFER COUNTER
-
- RDFILE DB MAXLEN+1 DUP (0); INPUT FILE NAME BUFFER
-
- WRFILE DB MAXLEN+1 DUP (0); OUTPUT FILE NAME BUFFER
-
- RDHAND DW (?) ; READ FILE HANDLE
-
- WRHAND DW (?) ; WRITE FILE HANDLE
-
- CHKACC DB (?) ; CHECKSUM ACCUMULATOR
-
- DSKPTR DW (?) ; DISK BUFFER POINTER
-
- MEMPTR DW (?) ; MEMORY POINTER
-
- MEMCNT DW (?) ; MEMORY COUNTER
-
- NUMREC DW (?) ; NUMBER OF RECORDS IN CURRENT LINE
-
- RECNUM DW (?) ; NUMBER OF BYTES FOR NUMREC RECORDS
-
- CURADD DW (?) ; CURRENT ADDRESS
-
- DB (0) ; DUMMY START OF MEMBUF
- MEMBUF DB MEMLEN DUP (0) ; MEMORY BUFFER
-
- DATA ENDS
- PAGE
- CODE SEGMENT ; CODE SEGMENT
- ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
-
- ; ****************************************************************
- ; ** **
- ; ** MAIN PROGRAM **
- ; ** **
- ; ****************************************************************
-
- DASM80 PROC FAR ;
-
- PUSH DS ;
- MOV AX,0 ;
- PUSH AX ; SET UP FOR A FAR RETURN TO DOS
-
- MOV AX,DATA ;
- MOV DS,AX ; SET UP DATA SEGMENT REGISTER
-
- MOV DX,OFFSET MRCOM ; POINT TO READING COMMAND LINE MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- CALL RCMD ; READ COMMAND LINE
-
- MOV DX,OFFSET MOPENR; POINT TO OPENING INPUT FILE MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- CALL OPENRD ; OPEN INPUT FILE FOR READ
-
- MOV DX,OFFSET MCHEX ; POINT TO CONVERTING HEX FILE MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- CALL CHEX ; CONVERT INPUT FILE
-
- MOV DX,OFFSET MOPENW; POINT TO OPENING OUTPUT FILE MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- CALL OPENWR ; OPEN OUTPUT FILE FOR WRITE
-
- MOV DX,OFFSET MDISS ; POINT TO DISASSEMBLING MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- CALL DISS ; DISASSEMBLE FILE
-
- MOV DX,OFFSET MCLOSW; POINT TO CLOSING WRITE FILE MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- CALL CLOSWR ; DISASSEMBLE FILE
-
- MOV DX,OFFSET MEXIT ; POINT TO EXITING MESSAGE
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- RET ; RETURN TO DOS
-
- DASM80 ENDP ;
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** READ COMMAND LINE **
- ; ** **
- ; ****************************************************************
-
- RCMD PROC NEAR ;
-
- MOV BX,80H ; POINT TO NUMBER OF RECEIVED CHARACTERS
- MOV CH,ES:[BX] ; LOAD NUMBER OF RECEIVED CHARACTERS
- OR CH,CH ; ZERO CHARACTERS?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- INC BX ; NO - POINT TO CHARACTERS
- MOV DI,OFFSET RDFILE; POINT TO INPUT FILE NAME BUFFER
- MOV CL,MAXLEN ; LOAD MAXIMUM FILE NAME LENGTH
-
- MOV AL,ES:[BX] ; READ NEXT CHARACTER
- INC BX ; ADVANCE POINTER
- DEC CH ; RETARD CHARACTER COUNTER - END?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- CMP AL,' ' ; NO - SPACE?
- JNZ RCMD25 ; NO - DISPLAY ERROR
-
- RCMD05:
- MOV AL,ES:[BX] ; YES - READ NEXT CHARACTER
- MOV [DI],AL ; WRITE TO INPUT FILE NAME BUFFER
- CMP AL,' ' ; SPACE?
- JZ RCMD10 ; YES - LOAD OUTPUT FILE NAME
-
- INC BX ; NO -
- INC DI ; - ADVANCE POINTERS
- DEC CH ; RETARD CHARACTER COUNTER - END?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- DEC CL ; NO - RETARD FILE NAME COUNTER - TOO LONG?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- JMP RCMD05 ; NO - CONTINUE
-
- RCMD10:
- INC BX ; ADVANCE COMMAND LINE POINTER
- DEC CH ; DECREMENT CHARACTER COUNTER - END?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- MOV DI,OFFSET WRFILE; NO - POINT TO OUTPUT FILE NAME BUFFER
- MOV CL,MAXLEN ; LOAD MAXIMUM FILE NAME LENGTH
-
- RCMD20:
- MOV AL,ES:[BX] ; READ NEXT CHARACTER
- CMP AL,' ' ; SPACE?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- MOV [DI],AL ; NO - WRITE TO OUTPUT FILE NAME BUFFER
- INC BX ;
- INC DI ; ADVANCE POINTERS
- DEC CH ; RETARD COUNTER - LAST CHARACTER?
- JZ RCMD30 ; YES - DONE
-
- DEC CL ; NO - RETARD COUNTER - FILE NAME TOO LONG?
- JZ RCMD25 ; YES - DISPLAY ERROR
-
- JMP RCMD20 ; NO - CONTINUE
-
- RCMD25:
- MOV DX,OFFSET MBCOM ; POINT TO BAD COMMAND LINE MESSAGE
- JMP MISERR ; DISPLAY ERROR MESSAGE AND EXIT TO DOS
-
- RCMD30:
- RET ;
-
- RCMD ENDP ;
-
- ; ****************************************************************
- ; ** **
- ; ** OPEN INPUT FILE FOR READ **
- ; ** **
- ; ****************************************************************
-
- OPENRD PROC NEAR ;
-
- MOV AH,OPEN ; LOAD OPEN FILE COMMAND
- MOV AL,RDACC ; LOAD READ ACCESS CODE
- MOV DX,OFFSET RDFILE; POINT TO INPUT FILE NAME
- INT DOSFUNC ; OPEN INPUT FILE - ERROR?
- JNC OPRD05 ; NO - STORE READ FILE HANDLE
-
- JMP DSKERR ; YES - DISPLAY ERROR
-
- OPRD05:
- MOV RDHAND,AX ; NO - STORE READ FILE HANDLE
- RET ; DONE
-
- OPENRD ENDP ;
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** CONVERT INPUT FILE **
- ; ** **
- ; ****************************************************************
-
- CHEX PROC NEAR ;
-
- CHEX10:
- DISKRD 1 ; READ ONE BYTE FROM DISK FILE - ERROR?
-
- CMP AX,01 ; NO - 1 CHARACTER?
- JZ CHEX11 ; YES - TEST FOR RECORD MARK
-
- JMP CHEX25 ; NO - DISPLAY ERROR
-
- CHEX11:
- MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
- MOV AL,[BX] ; LOAD RECEIVED CHARACTER
- CMP AL,':' ; RECORD MARK?
- JNZ CHEX10 ; NO - TRY AGAIN
-
- DISKRD 8 ; YES - READ EIGHT BYTES FROM DISK FILE - ERROR?
-
- MOV CHKACC,0 ; NO - INITIALIZE CHECKSUM ACCUMULATOR
- CMP AX,08 ; RECEIVE 8 CHARACTERS?
- JZ CHEX12 ; YES - CONVERT NUMBER OF BYTES IN RECORD
-
- JMP CHEX25 ; NO - DISPLAY ERROR
-
- CHEX12:
- MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
- CALL PACK ; CONVERT NUMBER OF BYTES IN RECORD
- MOV AH,0 ;
- MOV NUMREC,AX ; STORE
- CALL PACK ; CONVERT HIGH START ADDRESS
- MOV DH,AL ; STORE
- CALL PACK ; CONVERT LOW START ADDRESS
- MOV DL,AL ; STORE
- CALL PACK ; CONVERT RECORD INDICATOR
- CMP AL,DATIND ; DATA INDICATOR?
- JNZ CHEX20 ; NO - TEST FOR END OF FILE INDICATOR
-
- MOV BX,OFFSET MEMBUF; YES - POINT TO MEMBUF
- ADD BX,DX ; COMPUTE MEMBUF ADDRESS FOR THIS RECORD
- MOV MEMPTR,BX ; STORE
- MOV AX,NUMREC ; LOAD NUMBER OF RECORDS
- ADD AX,AX ; COMPUTE NUMBER OF DATA CHARACTERS
- ADD AX,4 ; ADD CHECKSUM AND TERMINATOR CHARACTER COUNT
- MOV RECNUM,AX ; STORE
- DISKRD RECNUM ; YES - READ RECNUM BYTES FROM DISK FILE - ERROR?
-
- MOV BX,OFFSET DSKBUF; NO - POINT TO DISK BUFFER
- MOV DSKPTR,BX ; INITITIALIZE DISK BUFFER POINTER
- CMP RECNUM,CX ; RECEIVED CORRECT NUMBER OF CHARACTERS?
- JZ CHEX14 ; YES - CONVERT RECORD
-
- JMP CHEX25 ; NO - DISPLAY ERROR
-
- CHEX14:
- MOV CX,NUMREC ; LOAD COUNTER
- JCXZ CHEX21 ; ZERO BYTES? - YES - LOAD AND TEST
- ; CHECKSUM AND TERMINATOR
-
- CHEX15:
- MOV BX,DSKPTR ; NO - LOAD DISK BUFFER POINTER
- CALL PACK ; CONVERT DATA
- MOV DSKPTR,BX ; STORE DISK BUFFER POINTER
- MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
- MOV [BX],AL ; STORE DATA
- INC MEMPTR ; ADVANCE MEMORY BUFFER POINTER
- DEC CX ; RETARD COUNTER - DONE?
- JNZ CHEX15 ; NO - CONTINUE
-
- MOV BX,DSKPTR ; YES - LOAD DISK BUFFER POINTER
- CALL PACK ; CONVERT CHECKSUM
- MOV CL,AL ; STORE CHECKSUM
- MOV AL,CHKACC ; LOAD CHECKSUM ACCUMULATOR
- SUB AL,CL ; ADJUST CHECKSUM
- NOT AL ;
- INC AL ; COMPUTE 2'S COMPLEMENT OF CHECKSUM
- CMP AL,CL ; CHECKSUMS MATCH?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- CMP BYTE PTR[BX],CR ; YES - TERMINATED WITH <CR>?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- INC BX ; YES - POINT TO LINE FEED
- CMP BYTE PTR[BX],LF ; LINE FEED?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- JMP CHEX10 ; YES - CONTINUE
-
- CHEX20:
- CMP AL,EOFIND ; END OF FILE INDICATOR?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- DISKRD 4 ; YES - READ 4 BYTES FROM DISK FILE - ERROR?
- CMP AX,4 ; NO - 4 CHARACTERS?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- CHEX21:
- MOV BX,OFFSET DSKBUF; YES - POINT TO DISK BUFFER
- CALL PACK ; CONVERT CHECKSUM
- MOV CL,AL ; STORE CHECKSUM
- MOV AL,CHKACC ; LOAD CHECKSUM ACCUMULATOR
- SUB AL,CL ; ADJUST CHECKSUM
- NOT AL ;
- INC AL ; COMPUTE 2'S COMPLEMENT OF CHECKSUM
- CMP AL,CL ; CHECKSUMS MATCH?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- CMP BYTE PTR[BX],CR ; YES - TERMINATED WITH <CR>?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- INC BX ; YES - POINT TO LINE FEED
- CMP BYTE PTR[BX],LF ; LINE FEED?
- JNZ CHEX25 ; NO - DISPLAY ERROR
-
- RET ; YES - DONE
-
- CHEX25:
- MOV DX,OFFSET MBHEX ; POINT TO BAD HEX DATA MESSAGE
- JMP MISERR ; DISPLAY ERROR MESSAGE AND EXIT TO DOS
-
- CHEX ENDP ;
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** OPEN OUTPUT FILE FOR WRITE **
- ; ** **
- ; ****************************************************************
-
- OPENWR PROC NEAR ;
-
- MOV AH,CLOSE ; LOAD CLOSE FILE COMMAND
- MOV BX,RDHAND ; LOAD INPUT FILE HANDLE
- INT DOSFUNC ; CLOSE THE INPUT FILE - ERROR?
- JNC OPWR05 ; NO - OPEN WRITE FILE
-
- JMP DSKERR ; YES - DISPLAY ERROR
-
- OPWR05:
- MOV AH,CREATE ; LOAD CREATE FILE COMMAND
- MOV CX,WRATT ; LOAD WRITE FILE ATTRIBUTE
- MOV DX,OFFSET WRFILE; POINT TO OUTPUT FILE NAME
- INT DOSFUNC ; OPEN OUTPUT FILE - ERROR?
- JNC OPWR10 ; NO - STORE WRITE FILE HANDLE
-
- JMP DSKERR ; YES - DISPLAY ERROR
-
- OPWR10:
- MOV WRHAND,AX ; STORE WRITE FILE HANDLE
- RET ; DONE
-
- OPENWR ENDP ;
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** DISASSEMBLE MEMORY BUFFER **
- ; ** **
- ; ****************************************************************
-
- DISS PROC NEAR ;
-
- MOV BX,OFFSET MEMBUF-1; POINT TO MEMORY BUFFER
- MOV MEMPTR,BX ; INITIALIZE MEMORY POINTER
- MOV BX,MEMLEN+2 ; LOAD NUMBER OF BYTES TO DISSASEMBLE
- MOV MEMCNT,BX ; STORE
-
- DISS05:
- MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
- MOV DSKPTR,BX ; INITIALIZE DISK BUFFER POINTER
- MOV BX,0 ;
- MOV DSKCNT,BX ; CLEAR DISK BUFFER COUNTER
- MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
- DEC BX ; RETARD MEMORY BUFFER COUNTER - END OF FILE?
- MOV MEMCNT,BX ; (STORE)
- JZ DISS10 ; YES - WRITE "END" TO OUTPUT FILE
-
- MOV BX,MEMPTR ; NO - LOAD MEMORY BUFFER POINTER
- MOV AL,[BX] ; LOAD NEXT OPCODE
- OR AL,AL ; ZERO?
- JNZ DISS15 ; NO - FIND IT'S MNEMONIC
-
- DISS10:
- PUSH BX ; YES - SAVE MEMORY BUFFER POINTER
- MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
- DEC BX ; END OF FILE?
- MOV MEMCNT,BX ; (STORE)
- POP BX ; (RESTORE MEMORY POINTER)
- JNZ DISS11 ; NO - POINT TO NEXT BYTE
-
- JMP DISS60 ; YES - WRITE "END" TO DISK
-
- DISS11:
- INC BX ; POINT TO NEXT BYTE
- MOV AL,[BX] ; LOAD IT
- OR AL,AL ; ZERO?
- JZ DISS10 ; YES - CONTINUE
-
- MOV MEMPTR,BX ; NO - STORE MEMORY BUFFER POINTER
- CALL ORGWR ; WRITE ORG LINE TO DISK
- JMP DISS05 ; CONTINUE
-
- DISS15:
- MOV DX,BX ; LOAD CURRENT MEMORY BUFFER LOCATION
- SUB DX,OFFSET MEMBUF; COMPUTE CURRENT ADDRESS
- MOV CURADD,DX ; STORE
- MOV CL,[BX] ;
- MOV CH,0 ; LOAD OPCODE
- INC CX ; ADJUST
- MOV BX,OFFSET MNEM ; POINT TO MNEMONIC TABLE
-
- DISS20:
- DEC CX ; RETARD OPCODE - DONE?
- JZ DISS30 ; YES - WRITE TAB TO DISK BUFFER
-
- DISS25:
- MOV AL,[BX] ; NO - LOAD NEXT CHARACTER
- INC BX ; ADVANCE MNEMONIC TABLE POINTER
- CMP AL,RS ; RS?
- JZ DISS20 ; YES - RETARD OPCODE AND TEST FOR DONE
-
- JMP DISS25 ; NO - TEST NEXT CHARACTER FOR RS
-
- DISS30:
- PUSH BX ; SAVE MNEMONIC POINTER
- MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
- MOV BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
- INC AX ; ADVANCE
- MOV DSKCNT,AX ; STORE
- PUSH BX ;
- POP DI ; LOAD DISK BUFFER POINTER IN DX
- POP BX ; RESTORE MNEMONIC POINTER
-
- DISS35:
- MOV AL,[BX] ; LOAD MNEMONIC CHARACTER
- CMP AL,RS ; RS?
- JZ DISS40 ; YES - STORE DISK BUFFER POINTER
-
- MOV [DI],AL ; NO - WRITE CHARACTER TO DISK BUFFER
- INC DI ; ADVANCE DISK BUFFER POINTER
- INC BX ; ADVANCE MNEMONIC POINTER
- MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
- INC AX ; ADVANCE
- MOV DSKCNT,AX ; STORE
- JMP DISS35 ; TEST NEXT CHARACTER FOR RS
-
- DISS40:
- XCHG BX,DI ; LOAD DISK BUFFER POINTER IN BX
- MOV DSKPTR,BX ; STORE DISK BUFFER POINTER
- MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
- MOV CH,0 ;
- MOV CL,[BX] ; LOAD OP-CODE
- INC BX ; ADVANCE MEMORY BUFFER POINTER
- MOV MEMPTR,BX ; STORE
- CALL OPBYTE ; COMPUTE NUMBER OF BYTES FOR THIS OPCODE
- MOV AL,CL ; LOAD NUMBER OF BYTES
- OR AL,AL ; ZERO BYTES?
- JNZ DISS41 ; NO - TEST FOR ONE BYTE
-
- MOV BX,MEMPTR ; YES - LOAD MEMORY BUFFER POINTER
- DEC BX ; ADJUST
- MOV AL,[BX] ; LOAD "OP-CODE"
- MOV BX,DSKPTR ; LOAD DISK POINTER
- MOV BYTE PTR[BX],'0'; WRITE LEADING ZERO TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV DSKPTR,BX ; STORE
- CALL EXPAND ; WRITE "OP-CODE" TO DISK BUFFER
- MOV BX,DSKPTR ; LOAD DISK POINTER
- MOV BYTE PTR[BX],'H'; WRITE "H" TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV DSKPTR,BX ; STORE
- ADD DSKCNT,2 ; ADVANCE DISK COUNTER
- JMP DISS55 ; WRITE "TAB,;,CR,LF" TO OUTPUT FILE
-
- DISS41:
- DEC AL ; ONE BYTE?
- JNZ DISS42 ; NO - TEST FOR TWO BYTES
-
- JMP DISS55 ; YES - WRITE "TAB,;,CR,LF" TO OUTPUT FILE
-
- DISS42:
- DEC AL ; TWO BYTES?
- JNZ DISS45 ; NO - JUMP TO THREE BYTE HANDLER
-
- MOV BX,MEMCNT ; YES - LOAD MEMORY BUFFER COUNTER
- DEC BX ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
- MOV MEMCNT,BX ; (STORE)
- JNZ DISS43 ; NO - WRITE ADDRESS TO DISK BUFFER
-
- JMP DISS60 ; YES - WRITE "END" TO OUTPUT FILE
-
- DISS43:
- MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
- MOV BYTE PTR[BX],'0'; LOAD LEADING ZERO
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV DSKPTR,BX ; STORE
- MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
- INC AX ; ADVANCE
- MOV DSKCNT,AX ; STORE
- MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
- MOV AL,[BX] ; LOAD NEXT BYTE
- INC BX ; ADVANCE POINTER
- MOV MEMPTR,BX ; STORE
- CALL EXPAND ; CONVERT TO ASCII IN DISK BUFFER
- JMP DISS50 ; WRITE "H" TO DISK BUFFER
-
- DISS45:
- MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
- DEC BX ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
- JNZ DISS46 ; NO - RETARD AGAIN
-
- JMP DISS60 ; YES - WRITE "END" TO OUTPUT FILE
-
- DISS46:
- DEC BX ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
- MOV MEMCNT,BX ; (STORE)
- JNZ DISS47 ; NO - WRITE ADDRESS TO DISK BUFFER
-
- JMP DISS60 ; YES - WRITE "END" TO OUTPUT FILE
-
- DISS47:
- MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
- MOV BYTE PTR[BX],'0'; LOAD LEADING ZERO
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV DSKPTR,BX ; STORE
- MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
- INC AX ; ADVANCE
- MOV DSKCNT,AX ; STORE
- MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
- MOV AL,[BX] ; LOAD LOW ADDRESS BYTE
- PUSH AX ; STORE
- INC BX ; ADVANCE MEMORY BUFFER POINTER
- MOV AL,[BX] ; LOAD HIGH ADDRESS BYTE
- INC BX ; ADVANCE MEMORY BUFFER POINTER
- MOV MEMPTR,BX ; STORE
- CALL EXPAND ; CONVERT TO ASCII IN DISK BUFFER
- POP AX ; RESTORE LOW ADDRESS BYTE
- CALL EXPAND ; CONVERT TO ASCII
-
- DISS50:
- MOV BX,DSKPTR ; NO - LOAD DISK BUFFER POINTER
- MOV BYTE PTR[BX],'H'; WRITE HEX INDICATOR
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV DSKPTR,BX ; STORE
- MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
- INC AX ; ADVANCE
- MOV DSKCNT,AX ; STORE
-
- DISS55:
- MOV CX,DSKCNT ; LOAD DISK BUFFER COUNTER
- MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
-
- DISS56:
- MOV CH,0 ; CLEAR CHARACTER COUNTER
-
- DISS57:
- MOV AL,[BX] ; LOAD NEXT CHARACTER
- INC BX ; ADVANCE DISK BUFFER POINTER
- INC CH ; ADVANCE CHARACTER COUNTER
- DEC CL ; LAST CHARACTER?
- JZ DISS58 ; YES - DECIDE WHETHER ONE OR TWO TABS
-
- CMP AL,TAB ; NO - TAB?
- JZ DISS56 ; YES - CLEAR CHARACTER COUNTER
-
- JMP DISS57 ; NO - TEST NEXT CHARACTER
-
- DISS58:
- MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
- MOV AL,8 ;
- CMP AL,CH ; LESS THAN EIGHT CHARACTERS SINCE LAST TAB?
- JBE DISS61 ; NO - WRITE ONE TAB TO DISK BUFFER
-
- MOV BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- INC DSKCNT ; ADVANCE DISK BUFFER COUNTER
-
- DISS61:
- MOV BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV BYTE PTR[BX],';'; WRITE ";" TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV BYTE PTR[BX],' '; WRITE " " TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV DSKPTR,BX ; STORE
- MOV DX,CURADD ; LOAD CURRENT ADDRESS
- MOV AL,DH ; LOAD HIGH ADDRESS
- CALL EXPAND ; WRITE TO DISK BUFFER
- MOV AL,DL ; LOAD LOW ADDRESS
- CALL EXPAND ; WRITE TO DISK BUFFER
- MOV BYTE PTR[BX],CR ; WRITE <CR> TO DISK BUFFER
- INC BX ; ADVANCE DISK BUFFER POINTER
- MOV BYTE PTR[BX],LF ; WRITE LINE FEED TO DISK BUFFER
- ADD DSKCNT,5 ; ADD TAB AND TERMINATOR COUNT
- DISKWR DSKCNT ; WRITE TO DISK FILE - ERROR?
-
- CMP AX,DSKCNT ; NO - ALL BYTES WRITTEN?
- JZ DISS59 ; YES - CONTINUE
-
- MOV AX,0 ; NO - LOAD ERROR NUMBER
- JMP DSKERR ; DISPLAY ERROR
-
- DISS59:
- JMP DISS05 ; CONTINUE
-
- DISS60:
- MOV BX,OFFSET MSGEND; POINT TO "END" STRING
- MOV DI,OFFSET DSKBUF; POINT TO DISK BUFFER
- MOV CX,LENEND ; LOAD MESSAGE LENGTH
-
- DISS65:
- MOV AL,[BX] ; LOAD FROM STRING
- MOV [DI],AL ; WRITE TO DISK BUFFER
- INC BX ; ADVANCE STRING POINTER
- INC DI ; ADVANCE DISK BUFFER POINTER
- DEC CX ; RETARD COUNTER - DONE?
- JNZ DISS65 ; NO - CONTINUE
-
- DISKWR LENEND ; YES - WRITE TO DISK - ERROR?
-
- CMP AX,LENEND ; NO - ALL BYTES WRITTEN?
- JZ DISS70 ; YES - DONE
-
- MOV AX,0 ; NO - LOAD ERROR NUMBER
- JMP DSKERR ; NO - DISPLAY ERROR
-
- DISS70:
- RET ; DONE
-
- DISS ENDP ;
-
- PAGE
- ; ****************************************************************
- ; ** **
- ; ** CLOSE OUTPUT FILE **
- ; ** **
- ; ****************************************************************
-
- CLOSWR PROC NEAR ;
-
- MOV AH,CLOSE ; LOAD CLOSE FILE COMMAND
- MOV BX,WRHAND ; LOAD OUTPUT FILE HANDLE
- INT DOSFUNC ; CLOSE THE OUTPUT FILE - ERROR?
- JNC CLOS05 ; NO - DONE
-
- JMP DSKERR ; YES - DISPLAY ERROR
-
- CLOS05:
- RET ;
-
- CLOSWR ENDP
- PAGE
- SBRS PROC NEAR ;
-
- ; ****************************************************************
- ; ** **
- ; ** SUBROUTINES **
- ; ** **
- ; ****************************************************************
-
- ; ****************************************************************
- ; ** FUNCTION: CONVERT ASCII TO HEXADECIMAL **
- ; ** ENTRY: ASCII REPRESENTATION OF VALID HEX NUMBER IN AL **
- ; ** USES: AL **
- ; ** EXIT: HEX NUMBER IN AL **
- ; ** CALLS: NONE **
- ; ****************************************************************
-
- ASCHEX:
- CMP AL,'9'+1 ; IS IT LESS THAN OR EQUAL TO 9?
- JLE ASC05 ; YES - JUMP PAST HEX CONVERSION
-
- ADD AL,9 ; NO - ADD HEX OFFSET
-
- ASC05:
- AND AL,0FH ; STRIP ASCII BIAS
- RET ;
- PAGE
- ; ****************************************************************
- ; ** FUNCTION: CONVERT 8 BIT VALUE TO TWO ASCII CHARACTERS **
- ; ** AND WRITE THEM TO MEMORY POINTED TO BY DSKPTR **
- ; ** ENTRY: A=8 BIT VALUE TO BE CONVERTED **
- ; ** USES: BX **
- ; ** EXIT: BX=END VALUE OF DSKPTR **
- ; ** CALLS: HEXASC **
- ; ****************************************************************
-
- EXPAND:
- PUSHF ;
- PUSH AX ;
- PUSH CX ;
- PUSH AX ; SAVE BYTE TO BE EXPANDED
- MOV CL,4 ;
- ROL AL,CL ; EXCHANGE NIBBLES
- CALL HEXASC ; CONVERT HEX TO ASCII
- MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
- MOV [BX],AL ; WRITE TO MEMORY
- INC BX ; ADVANCE MEMORY POINTER
- POP AX ; RESTORE ORIGINAL BYTE
- CALL HEXASC ; CONVERT HEX TO ASCII
- MOV [BX],AL ; WRITE TO MEMORY
- INC BX ; ADVANCE MEMORY POINTER
- MOV DSKPTR,BX ; STORE NEW DISK BUFFER POINTER
- MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
- INC AX ;
- INC AX ; ADVANCE
- MOV DSKCNT,AX ; STORE
- POP CX ;
- POP AX ;
- POPF ;
- RET ;
-
-
-
- ; ****************************************************************
- ; ** FUNCTION: CONVERT 4 BIT VALUE TO ASCII **
- ; ** ENTRY: LOWER NIBBLE OF A=VALUE TO BE CONVERTED **
- ; ** USES: AL **
- ; ** EXIT: A=ASCII CHARACTER **
- ; ** CALLS: NONE **
- ; ****************************************************************
-
- HEXASC:
- AND AL,0FH ; ISOLATE LOWER NIBBLE
- CMP AL,9+1 ; IS IT LESS THAN OR EQUAL TO 9?
- JL HXAS05 ; YES - JUMP PAST HEX CONVERSION
-
- SUB AL,9 ; NO - SUBTRACT HEX OFFSET
- OR AL,40H ; COMBINE WITH HEX ASCII BIAS
- RET ;
-
- HXAS05:
- OR AL,30H ; COMBINE WITH DECIMAL ASCII BIAS
- RET ;
- PAGE
- ; ****************************************************************
- ; ** FUNCTION: WRITE MESSAGE TO STANDARD OUTPUT **
- ; ** ENTRY: DX=START ADDRESS OF MESSAGE STRING **
- ; ** USES: ??? **
- ; ** EXIT: NONE **
- ; ** CALLS: NONE **
- ; ****************************************************************
-
- MSGCO:
- MOV AH,PR_STR ; LOAD PRINT STRING COMMAND
- INT DOSFUNC ; PRINT STRING
- RET ; DONE
- PAGE
- ; ****************************************************************
- ; ** FUNCTION: COMPUTE NUMBER OF BYTES FOR OP-CODES **
- ; ** ENTRY: CX=OPCODE **
- ; ** USES: CL **
- ; ** EXIT: NUMBER OF BYTES IN CL **
- ; ** CALLS: NONE **
- ; ****************************************************************
-
- OPBYTE:
- PUSHF ; SAVE FLAGS
- PUSH AX ; SAVE AX
- PUSH CX ; SAVE CX
- PUSH BX ; SAVE BX
- MOV AL,CL ; LOAD OP-CODE
- CMP AL,40H ; LESS THAN 40H?
- JC OPB10 ; YES - LOOK UP NUMBER OF BYTES
-
- CMP AL,0C0H ; NO - GREATER THAN OR EQUAL TO C0H?
- JNC OPB05 ; YES - ADJUST OP-CODE
-
- MOV AL,01 ; NO - NUMBER OF BYTES IS 1
- JMP OPB25 ; DONE
-
- OPB05:
- MOV AL,80H ;
- ADD AL,CL ; ADJUST OP-CODE
- MOV CL,AL ; STORE
-
- OPB10:
- AND AL,03H ;
- ROL AL,1 ; COMPUTE NUMBER OF SHIFTS
- PUSH AX ; STORE
- MOV AL,CL ; LOAD OP-CODE
- AND AL,0FCH ;
- ROR AL,1 ;
- ROR AL,1 ; DIVIDE BY 4
- MOV CL,AL ; STORE
- MOV BX,OFFSET BYTES ; POINT TO BYTES TABLE
- ADD BX,CX ; ADD OFFSET
- MOV CL,[BX] ; LOAD NUMBER OF BYTES
- POP AX ; LOAD NUMBER OF SHIFTS
- MOV CH,AL ; STORE
- INC CH ; ADJUST
- MOV AL,CL ; LOAD NUMBER OF BYTES
-
- OPB15:
- DEC CH ; DONE?
- JZ OPB20 ; YES - ISOLATE NUMBER OF BYTES
-
- ROR AL,1 ; NO - SHIFT
- JMP OPB15 ; CONTINUE
-
- OPB20:
- AND AL,03H ; ISOLATE NUMBER OF BYTES
-
- OPB25:
- POP BX ; RESTORE BX
- POP CX ; RESTORE CX
- MOV CL,AL ; LOAD NUMBER OF BYTES IN C
- POP AX ; RESTORE A
- POPF ; RESTORE FLAGS
- RET ;
-
- ; ****************************************************************
- ; ** FUNCTION: WRITE ORG STRING TO DISK **
- ; ** ENTRY: NONE **
- ; ** USES: ALL **
- ; ** EXIT: ORG STRING WRITTEN TO DISK **
- ; ** CALLS: EXPAND **
- ; ****************************************************************
-
- ORGWR:
- MOV DSKCNT,0 ; CLEAR DISK BUFFER COUNTER
- MOV CX,LENORG ; LOAD "ORG" MESSAGE LENGTH
- MOV DI,OFFSET MSGORG; POINT TO "ORG" STRING
- MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
-
- ORGW05:
- MOV AL,[DI] ; LOAD NEXT CHARACTER OF "ORG" STRING
- MOV [BX],AL ; WRITE IT TO DISK BUFFER
- INC DI ;
- INC BX ; ADVANCE POINTERS
- INC DSKCNT ; ADVANCE DISK BUFFER COUNTER
- DEC CX ; DECREMENT COUNTER - DONE?
- JNZ ORGW05 ; NO - CONTINUE
-
- MOV DSKPTR,BX ; YES - STORE DISK BUFFER POINTER
- MOV DX,OFFSET MEMBUF; LOAD MEMORY BUFFER ADDRESS
- MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
- MOV AL,BL ; LOAD LOW MEMORY BUFFER POINTER
- SUB AL,DL ; COMPUTE LOW ORG ADDRESS
- PUSH AX ; STORE
- MOV AL,BH ; LOAD HIGH MEMORY BUFFER POINTER
- SBB AL,DH ; COMPUTE HIGH ORG ADDRESS
- CALL EXPAND ; WRITE TO DISK BUFFER
- POP AX ; LOAD LOW ORG ADDRESS
- CALL EXPAND ; WRITE TO DISK BUFFER
- MOV BYTE PTR[BX],'H'; WRITE HEX INDICATOR TO DISK BUFFER
- INC BX ; ADVANCE POINTER
- MOV BYTE PTR[BX],CR ; WRITE <CR> TO DISK BUFFER
- INC BX ; ADVANCE POINTER
- MOV BYTE PTR[BX],LF ; WRITE LINE FEED TO DISK BUFFER
- ADD DSKCNT,3 ; ADJUST DISK BUFFER COUNTER
- DISKWR DSKCNT ; WRITE DKSCNT BYTES TO DISK - ERROR?
-
- CMP AX,DSKCNT ; NO - ALL BYTES WRITTEN?
- JZ ORGW10 ; YES - DONE
-
- POP AX ; NO - RESTORE STACK
- MOV AX,0 ; LOAD ERROR NUMBER
- JMP DSKERR ; DISPLAY ERROR
-
- ORGW10:
- RET ; DONE
-
-
-
- ; ****************************************************************
- ; ** FUNCTION: CONVERT TWO ASCII CHARACTERS TO 8 BIT NUMBER **
- ; ** ENTRY: BX=START ADDRESS OF VALID ASCII HEX CHARACTERS **
- ; ** USES: AL, BX **
- ; ** EXIT: A;=8 BIT NUMBER, BX=BX+2 **
- ; ** CALLS: ASCHEX **
- ; ****************************************************************
-
- PACK:
- PUSH CX ; SAVE CX
- MOV AL,[BX] ; LOAD CHARACTER
- CALL ASCHEX ; CONVERT ASCII CHARACTER TO HEX
- MOV CL,4 ;
- ROL AL,CL ; EXCHANGE NIBBLES
- MOV CH,AL ; STORE
- INC BX ; POINT TO NEXT CHARACTER
- MOV AL,[BX] ; LOAD NEXT CHARACTER
- CALL ASCHEX ; CONVERT ASCII CHARACTER TO HEX
- OR AL,CH ; COMBINE NIBBLES
- INC BX ; POINT TO NEXT CHARACTER
- ADD CHKACC,AL ; UPDATE CHECKSUM ACCUMULATOR
- POP CX ; RESTORE CX
- RET ;
-
- SBRS ENDP ;
- PAGE
- ERRHAN PROC FAR
-
- ; ****************************************************************
- ; ** **
- ; ** DISK ERROR HANDLER **
- ; ** **
- ; ****************************************************************
-
- DSKERR:
- MOV DX,OFFSET MDISK0; POINT TO DISK ERROR MESSAGE 0
- OR AX,AX ; ERROR 0?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MDISK1; NO - POINT TO DISK ERROR MESSAGE 1
- DEC AX ; ERROR 1?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MDISK2; NO - POINT TO DISK ERROR MESSAGE 2
- DEC AX ; ERROR 2?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MDISK3; NO - POINT TO DISK ERROR MESSAGE 3
- DEC AX ; ERROR 3?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MDISK4; NO - POINT TO DISK ERROR MESSAGE 4
- DEC AX ; ERROR 4?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MDISK5; NO - POINT TO DISK ERROR MESSAGE 5
- DEC AX ; ERROR 5?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MDISK6; NO - POINT TO DISK ERROR MESSAGE 6
- DEC AX ; ERROR 6?
- JZ MISERR ; YES - DISPLAY ERROR MESSAGE
-
- MOV DX,OFFSET MUKNOW; NO - POINT TO UNKNOWN DISK ERROR MESSAGE
- JMP MISERR ; DISPLAY ERROR MESSAGE
-
-
-
- ; ****************************************************************
- ; ** **
- ; ** MISCELANEOUS ERROR HANDLER **
- ; ** **
- ; ****************************************************************
-
- MISERR:
- CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
- POP AX ; RESTORE STACK
- RET ; RETURN TO DOS
-
- ERRHAN ENDP ;
-
- CODE ENDS ;
-
- END DASM80 ;